package org.example.controller;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.example.domain.beans.JwtParseInfo;
import org.example.domain.dto.LoginDto;
import org.example.domain.dto.TokenDto;
import org.example.domain.entity.Users;
import org.example.domain.model.Result;
import org.example.service.IFmFrontedSysUserService;
import org.example.util.FmFrontedJwtUtils;
import org.example.util.FmFrontedSignatureStatus;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;

@RestController
@RequestMapping("/user")
public class FmFrontedLoginController {
    private IFmFrontedSysUserService iFmFrontedSysUserService;
    private Log log= LogFactory.getLog(FmFrontedLoginController.class);
    private FmFrontedJwtUtils fmFrontedJwtUtils;

    public FmFrontedLoginController(IFmFrontedSysUserService iFmFrontedSysUserService, FmFrontedJwtUtils fmFrontedJwtUtils) {
        this.iFmFrontedSysUserService = iFmFrontedSysUserService;
        this.fmFrontedJwtUtils = fmFrontedJwtUtils;
    }
    @PostMapping("/usermsg")
    public Result queryUserByName(@RequestBody Map<String,String > username){
        Users users = iFmFrontedSysUserService.queryUserByName(username.get("username"));
        return Result.buildSuccess(users);
    }

    @PostMapping("/login")
    public Result loginInfo(@RequestBody LoginDto loginDto){
        log.info(String.format("username:%s,password:%s",loginDto.getUsername(),loginDto.getPassword()));
        Result login = iFmFrontedSysUserService.login(loginDto);
        return login;
    }
    @PostMapping("/inquire")
    public Result queryNameUser(@RequestBody Map<String,String> userName){
        Users users = iFmFrontedSysUserService.queryUserByName(userName.get("username"));
        if (users==null){
            return Result.buildSuccess(1);
        }else {
            return Result.buildFail();
        }

    }
    @PostMapping("/registered")
    public Result registeredUser(@RequestBody Map<String ,String > usermessage){
        String s = iFmFrontedSysUserService.registeredUser(usermessage);
        return Result.buildSuccess(s);
    }


    /***
     * 需要用户带access_token和refresh_token来换取新的access_token
     * 1.access_token必须是过期状态；如果不是过期状态则不允许换取新的token
     * 2.需要校验refresh_token,是正常状态；
     * 3.如果refresh_token也是过期状态，那么就需要重新登录；如果是被篡改装填也需要重新登录
     * @return
     */
    @PostMapping("/refresh/token")
    public Result refreshToken(@RequestBody TokenDto tokenDto , HttpServletRequest request, HttpServletResponse response){
        String authorization = request.getHeader("Authorization");
        if(StringUtils.hasText(authorization)&&authorization.startsWith("Bearer ")){
            String access_token = authorization.replace("Bearer ", "");
            JwtParseInfo jwtParseInfo = fmFrontedJwtUtils.validateAccessJwt(access_token);
            switch (jwtParseInfo.getSignatureStatus()){
                //如果是过期状态才允许换新的token
                case expired://正常过期状态
                    //验证refresh_token
                    jwtParseInfo = fmFrontedJwtUtils.validateRefreshJwt(tokenDto.getRefreshToken());
                    //refresh_token是正常状态
                    if(FmFrontedSignatureStatus.correct==jwtParseInfo.getSignatureStatus()){
                        //创建新的access_token
                        String newAccessToken= fmFrontedJwtUtils.createAccessToken(jwtParseInfo.getClaims().getSubject());
                        return Result.buildSuccess(newAccessToken);
                    }else {
                        response.setStatus(401);
                        return null;
                    }
                case correct:
                    return Result.buildSuccess(access_token);
                case tamper:
                    response.setStatus(401);
                    return null;
            }
        }
        return null;
    }
}
